package com.splic.product.service.impl;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alicp.jetcache.anno.CacheInvalidate;
import com.alicp.jetcache.anno.Cached;
import com.google.common.collect.Maps;
import com.splic.common.core.DeviceContext;
import com.splic.common.exception.BusinessException;
import com.splic.common.utils.DateUtils;
import com.splic.common.utils.RandomCodeUtil;
import com.splic.common.utils.StringUtils;
import com.splic.common.utils.security.Md5Utils;
import com.splic.product.domain.Channel;
import com.splic.product.domain.Product;
import com.splic.product.domain.ProductVersion;
import com.splic.product.mapper.ChannelMapper;
import com.splic.product.mapper.DeviceMapper;
import com.splic.product.mapper.ProductMapper;
import com.splic.product.service.ProductService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static com.splic.product.service.impl.WeatherServiceImpl.VivoSign.HmacSHA256;
import static com.splic.product.service.impl.WeatherServiceImpl.VivoSign.getUrlParamsFromMap;

/**
 * 产品Service业务层处理
 *
 * @author singe
 * @date 2022-01-04
 */
@Slf4j
@Service
public class ProductServiceImpl implements ProductService
{
    @Autowired
    private ProductMapper productMapper;

    @Autowired
    private DeviceMapper deviceMapper;

    @Autowired
    private ChannelMapper channelMapper;

    /**
     * 查询产品
     *
     * @param id 产品主键
     * @return 产品
     */
    @Override
    @Cached(name  = "product:", key = "#id" ,expire = 30,timeUnit = TimeUnit.MINUTES)
    public Product selectProductById(Long id)
    {
        return productMapper.selectProductById(id);
    }

    /**
     * 查询产品列表
     *
     * @param product 产品
     * @return 产品
     */
    @Override
    public List<Product> selectPageList(Product product)
    {
        return productMapper.selectProductList(product);
    }

    /**
     * 查询产品列表
     *
     * @param product 产品
     * @return 产品
     */
    @Override
    public List<Product> selectProductList(Product product)
    {
        return productMapper.selectProductList(product);
    }

    /**
     * 新增产品
     *
     * @param product 产品
     * @return 结果
     */
    @Override
    public int insert(Product product)
    {
        product.setPackageKey(RandomCodeUtil.getUUID());
        product.setCreateTime(DateUtils.getNowDate());
        return productMapper.insert(product);
    }

    /**
     * 修改产品
     *
     * @param product 产品
     * @return 结果
     */
    @Override
    public int update(Product product)
    {
        product.setUpdateTime(DateUtils.getNowDate());
        return productMapper.update(product);
    }


    /**
     * 删除产品信息
     *
     * @param id 产品主键
     * @return 结果
     */
    @Override
    public int deleteById(Long id)
    {
        return productMapper.deleteById(id);
    }

    @Override
    public List<Product> getByIds(Set<Long> productIdSet)
    {
        return productMapper.getByIds(productIdSet);
    }
    /**
     * 修改产品
     *
     * @param product 产品信息
     * @return 结果
     */
    @Override
    @Transactional
    @CacheInvalidate(name = "product:", key = "#product.id")
    @CacheInvalidate(name = "product:", key = "#product.packageKey")
    public int saveOrUpdate(Product product)
    {
        if(product.getId() != null){
            product.setUpdateTime(new Date());
            return this.update(product);
        }else{
            product.setCreateTime(new Date());
            return this.insert(product);
        }
    }

    @Override
    public Product getByPackageKey(String packageKey) {
        return productMapper.getByPackageKey(packageKey);
    }

    @Override
    public List<Product> selectProductByDeviceId(Long id) {
        return productMapper.selectProductByDeviceId(id);
    }

    @Override
    public List<Product> selectProductByUserId(Long id) {
        return productMapper.selectProductByUserId(id);
    }

    @Override
    public List<Map<String, String>> selectRecommendPageList(String channelReq, String phoneBrand) {
        List<Map<String, String>> mapList = new ArrayList<>();

        Product product = new Product();
        product.setIsRecommend(1);
        product.setPackageKey(DeviceContext.getProductPackageKey());
        List<Product> productList = productMapper.selectProductList(product);
        if (productList == null || productList.size() <= 0) {
            return mapList;
        }
//        不筛选渠道和手机品牌
        List<Product> resultList = new ArrayList<>();
        if (StringUtils.isEmpty(channelReq) && StringUtils.isEmpty(phoneBrand)) {
            resultList = productList;
        } else {
            List<String> allPhoneBrand = deviceMapper.selectAddPhoneBrandList();
            List<Long> allChannel = channelMapper.selectChannelList(null).stream().map(Channel::getId).collect(Collectors.toList());

            Channel channelBase = null;
            if (StringUtils.isNotEmpty(channelReq)) {
                channelBase = channelMapper.selectChannelByName(channelReq);
            }
            for (Product p : productList) {
                String pb = p.getPhoneBrand();
                List<String> phoneBrandList;
                if (StringUtils.isNotEmpty(pb)) {
                    phoneBrandList = Arrays.stream(pb.split(",")).collect(Collectors.toList());
                } else {
                    phoneBrandList = new ArrayList<>();
                }
                List<String> excludePhoneBrand = new ArrayList<>();
                if (pb.contains("全部,")) {
                    excludePhoneBrand.addAll(allPhoneBrand);
                    excludePhoneBrand.removeAll(phoneBrandList);
                }

                String channel = p.getChannel();
                List<Long> channelList;
                if (StringUtils.isNotEmpty(channel)) {
                    channelList = Arrays.stream(channel.split(",")).mapToLong(Long::valueOf).boxed().collect(Collectors.toList());
                } else {
                    channelList = new ArrayList<>();
                }
                List<Long> excludeChannel = new ArrayList<>();
                if (channel.contains("1,")) {
                    excludeChannel.addAll(allChannel);
                    excludeChannel.removeAll(channelList);
                }

//            只筛选品牌
                if (channelBase == null && StringUtils.isNotEmpty(phoneBrand)) {
                    if ("全部".equals(pb)) {
                        resultList.add(p);
                    } else if (pb.contains("全部,")) {
                        if (!excludePhoneBrand.contains(phoneBrand)) {
                            resultList.add(p);
                        }
                    } else {
                        if (phoneBrandList.contains(phoneBrand)) {
                            resultList.add(p);
                        }
                    }
//             只筛选渠道
                } else if (channelBase != null && StringUtils.isEmpty(phoneBrand)) {
                    if ("1".equals(channel)) {
                        resultList.add(p);
                    } else if (channel.contains("1,")) {
                        if (!excludeChannel.contains(channelBase.getId())) {
                            resultList.add(p);
                        }
                    } else {
                        if (channelList.contains(channelBase.getId())) {
                            resultList.add(p);
                        }
                    }
//                渠道和品牌都筛选
                } else {
                    if (pb.contains("全部,")) {
                        if (excludePhoneBrand.contains(phoneBrand)) {
                            continue;
                        }
                    } else {
                        if (!phoneBrandList.contains(phoneBrand)) {
                            continue;
                        }
                    }

                    if ("1".equals(channel)) {
                        resultList.add(p);
                    } else if (channel.contains("1,")) {
                        if (!excludeChannel.contains(channelBase.getId())) {
                            resultList.add(p);
                        }
                    } else {
                        if (channelList.contains(channelBase.getId())) {
                            resultList.add(p);
                        }
                    }
                }
            }
        }
        if (resultList.size() > 0) {
            Map<String, String> map;
            for (Product p : resultList) {
                map = new HashMap<>();
                map.put("name", p.getName());
                map.put("icon", p.getIcon());
                map.put("introduction", p.getIntroduction());
                map.put("packageName", p.getPackageName());
                map.put("content", p.getContent());
                map.put("sort", String.valueOf(p.getSort()));
                mapList.add(map);
            }
        }
        return mapList;
    }

    @Override
    public Map<String, Object> isUpdateApp(String phoneBrand) {
        Map<String, Object> resultMap = new HashMap<>();
        String versionReq = DeviceContext.getVersion();
        String versionNoOld = versionReq.split("\\.")[2];
        int isTest = 0;
        if (versionReq.contains("test") || versionReq.contains("Test")) {
            isTest = 1;
        }
        ProductVersion version = productMapper.getVersionByPackageKey(DeviceContext.getProductPackageKey(), isTest);
        String versionNo = version.getVersion();
        boolean isUpdate = false;
        if (Integer.parseInt(versionNoOld) < Integer.parseInt(versionNo)) {
            if (StringUtils.isNotEmpty(phoneBrand)
                    && isTest == 0
                    && (("OPPO".equalsIgnoreCase(phoneBrand) || "realme".equalsIgnoreCase(phoneBrand) || "OnePlus".equalsIgnoreCase(phoneBrand) || "VIVO".equalsIgnoreCase(phoneBrand)))) {
                Product product = productMapper.getByPackageKey(DeviceContext.getProductPackageKey());
                try {
                    if ("OPPO".equalsIgnoreCase(phoneBrand) || "realme".equalsIgnoreCase(phoneBrand) || "OnePlus".equalsIgnoreCase(phoneBrand)) {
                        String time = String.valueOf(System.currentTimeMillis());
                        String oak = product.getOppoAk();
                        String secret = product.getOppoSecret();
                        String path = "/resopen/app/version/" + product.getPackageName();
                        String param = oak+secret+time+path;
                        String sign= Md5Utils.hash(param + param.length());
                        HttpResponse res = HttpRequest.get("https://appstore-openapi-cn.heytapmobi.com/resopen/app/version/ej.easyjoy.alarmandreminder.cn").header("oak", oak).header("sign", sign).header("t", String.valueOf(time)).execute();
                        System.out.println(res.body());
                        JSONObject jsonObject = JSONUtil.parseObj(res.body());
                        if ("200".equals(String.valueOf(jsonObject.get("status")))) {
                            JSONObject json = JSONUtil.parseObj(jsonObject.get("result"));
                            String versionOppo = String.valueOf(json.get("fullVersionCode"));
                            if (Integer.parseInt(versionOppo) > Integer.parseInt(versionNoOld)) {
                                isUpdate = true;
                            }
                        }
                    } else {
                        Map<String,String> bizParams = Maps.newHashMap();
                        bizParams.put("packageName", product.getPackageName());
                        String secret = product.getVivoSecret();
                        Map<String,Object> parmas = Maps.newHashMap();
                        parmas.put("account", product.getVivoAccount());
                        parmas.put("timestamp", System.currentTimeMillis());
                        parmas.put("bizParam", bizParams);
                        String sign =HmacSHA256(getUrlParamsFromMap(parmas), secret);
                        parmas.put("sign", sign);
                        String result2 = HttpRequest.post("https://developer-api.vivo.com.cn/gateway/developer/app/publish/v1/get-online-version")
                                .header("content-type", "application/json")//头信息，多个头信息多次调用此方法即可
                                .body(JSONUtil.toJsonStr(parmas))//表单内容
                                .timeout(20000)//超时，毫秒
                                .execute().body();
                        JSONObject jsonObject = JSONUtil.parseObj(result2);
                        if ("0".equals(String.valueOf(jsonObject.get("code")))) {
                            JSONObject json = JSONUtil.parseObj(jsonObject.get("data"));
                            String versionVivo = String.valueOf(json.get("versionCode"));
                            if (Integer.parseInt(versionVivo) > Integer.parseInt(versionNoOld)) {
                                isUpdate = true;
                            }
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    throw new BusinessException("应用商店API调取异常");
                }
            } else {
                isUpdate = true;
            }
        }
        if (isUpdate) {
            resultMap.put("version", version);
            if (version.getIsForce() == 0) {
//                自由更新
                resultMap.put("isUpdate", 0);
            } else {
//                强制更新
                resultMap.put("isUpdate", 1);
            }
        } else {
//            无需更新
            resultMap.put("isUpdate", -1);
        }
        return resultMap;
    }

    @Override
    public List<Map<String, Object>> selectProductVersionById(Long id) {
        return productMapper.selectProductVersionById(id);
    }

    @Override
    public ProductVersion selectVersionByVersionId(Long id) {
        return productMapper.selectVersionByVersionId(id);
    }

    @Override
    public int saveOrUpdateVersion(ProductVersion version) {
        if(version.getId() != null){
            version.setUpdateTime(new Date());
            return productMapper.updateVersion(version);
        }else{
            version.setCreateTime(new Date());
            return productMapper.insertVersion(version);
        }
    }

    @Override
    public int deleteVersion(List<String> ids) {
        return productMapper.deleteVersion(ids);
    }

    @Override
    public Map<String, Object> getOaidFile() {
        Product product = productMapper.getByPackageKey(DeviceContext.getProductPackageKey());
        Map<String, Object> map = new HashMap<>();
        map.put("oaidFile", product.getOaidFile());
        map.put("originName", product.getOriginName());
        map.put("originContent", product.getOriginContent());
        return map;
    }
}
